#include "at32_board.h"

int fputc(int ch, FILE *f)
{
    USART_SendData(USART1, (uint8_t) ch);
    while (USART_GetFlagStatus(USART1, USART_FLAG_TDE) == RESET);
    return ch;
}
/*
* Description: USART1 初始化(给主机发送数据)
* Input: None
* Output: None
*/
void usart1_init(void)
{
    GPIO_InitType GPIO_InitStructure;
    USART_InitType USART_InitStructure;
    NVIC_InitType NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_USART1, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_GPIOA, ENABLE);
	
	GPIO_PinAFConfig(GPIOA, GPIO_PinsSource9, GPIO_AF_1);
	GPIO_PinAFConfig(GPIOA, GPIO_PinsSource10, GPIO_AF_1);

    GPIO_InitStructure.GPIO_Pins = GPIO_Pins_9 | GPIO_Pins_10; //TX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
	GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	
	USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);
	
    USART_INTConfig(USART1, USART_INT_RDNE, ENABLE);
	USART_Cmd(USART1, ENABLE);
	
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

/*
*
*/
void usart2_init(void)
{
    GPIO_InitType GPIO_InitStructure;
    USART_InitType USART_InitStructure;
    NVIC_InitType NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_USART1, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_GPIOA, ENABLE);
	
	GPIO_PinAFConfig(GPIOA, GPIO_PinsSource2, GPIO_AF_1);    
	GPIO_PinAFConfig(GPIOA, GPIO_PinsSource3, GPIO_AF_1); 

    GPIO_InitStructure.GPIO_Pins = GPIO_Pins_2 | GPIO_Pins_3; //TX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
	GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	
	USART_InitStructure.USART_BaudRate = 19200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART2, &USART_InitStructure);
	
    USART_INTConfig(USART2, USART_INT_RDNE, ENABLE);
	USART_Cmd(USART2, ENABLE);
	
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void button_pin_init(void)
{
    GPIO_InitType GPIO_InitStructure;
    RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_GPIOA | RCC_AHBPERIPH_GPIOB | RCC_AHBPERIPH_GPIOC, ENABLE);

    GPIO_InitStructure.GPIO_Pins = GPIO_Pins_10 | GPIO_Pins_11; //BUTTON
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
	GPIO_InitStructure.GPIO_Pull = GPIO_Pull_PU;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pins = GPIO_Pins_0 | GPIO_Pins_1; //BUTTON
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
	GPIO_InitStructure.GPIO_Pull = GPIO_Pull_PD;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pins = GPIO_Pins_6; //CHECK
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
	GPIO_InitStructure.GPIO_Pull = GPIO_Pull_PU;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB, GPIO_Pins_6);

    GPIO_InitStructure.GPIO_Pins = GPIO_Pins_14 | GPIO_Pins_15; //BUTTON
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
	GPIO_InitStructure.GPIO_Pull = GPIO_Pull_PD;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pins = GPIO_Pins_12 | GPIO_Pins_13; //KNOB
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
	GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pins = GPIO_Pins_14 | GPIO_Pins_15; //KNOB
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
	GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
}

static volatile uint32_t key_events = 0;
static button_state_t button_state[6] = {0};
void button_task_Function(void *pvParameters)
{
	typedef struct
	{
		GPIO_Type* port;
		uint16_t pin;
        uint8_t active_level; // 0: low active, 1: high active
	}at32_pin_t;
	
	const at32_pin_t at32_pin[] = {{GPIOB, GPIO_Pins_10, 0}, {GPIOB, GPIO_Pins_11, 0}, {GPIOA, GPIO_Pins_0, 1}, 
								   {GPIOA, GPIO_Pins_1, 1}, {GPIOB, GPIO_Pins_14, 1},{GPIOB, GPIO_Pins_15, 1}};

    const uint32_t short_press_time = 40;   //ms
    const uint32_t long_press_time = 1000;   //ms

    for(uint8_t i = 0; i < 6; ++i)
    {
        button_state[i].press_tick = 0;
        button_state[i].long_trigger = 0;
    }
    
	while(1)
	{		
        uint32_t new_key_state = 0;

        for(uint8_t i = 0; i < 6; ++i)
        {
            if(GPIO_ReadInputDataBit(at32_pin[i].port, at32_pin[i].pin) == at32_pin[i].active_level)
            {
                new_key_state |= (1UL << i);
            }
            if(new_key_state & (1UL << i)) 
            {
                if(button_state[i].press_tick == 0) 
                {
                    button_state[i].press_tick = xTaskGetTickCount();
                } 
                else if((xTaskGetTickCount() - button_state[i].press_tick > long_press_time) &&(!button_state[i].long_trigger))
                {
                    DBUG_SHOW("long press %d\r\n", i);
                    key_events |= (1UL << (i + 6)); // long press event
                    button_state[i].long_trigger = 1;
                }
            } 
            else 
            {
                if(button_state[i].press_tick != 0) 
                {
                    uint32_t press_duration = xTaskGetTickCount() - button_state[i].press_tick;
                    if(press_duration >= short_press_time && press_duration < long_press_time && !button_state[i].long_trigger) 
                    {
                        DBUG_SHOW("short press %d\r\n", i);
                        key_events |= (1UL << i); // short press event
                    }
                }
                button_state[i].press_tick = 0;
                button_state[i].long_trigger = 0;
            }
        }
		vTaskDelay(5);
	}
}

uint8_t bsp_get_key_event(uint8_t event_id) 
{
    if(event_id >= KEY_MAX) return 0;
    return (key_events & (1UL << event_id)) ? 1 : 0;
}

void bsp_clear_key_event(uint8_t event_id) 
{
    if(event_id < KEY_MAX) {
        key_events &= ~(1UL << event_id);
    }
}

